/**
 * OutputPlan 组件处理短期预测的输出计划的渲染和管理。
 * 它允许用户添加、删除和修改输出计划，配置价格限制，并引用策略。
 *
 * @component
 * @param {Object} props - 组件的属性。
 * @param {boolean} props.loading - 指示组件是否处于加载状态。
 * @param {Object} props.formValue - 组件中使用的表单值。
 * @param {Object} props.outputPlanData - 输出计划的数据。
 * @param {Array} props.buttonPermissions - 按钮的权限。
 * @param {number} props.power - 电力值。
 * @param {Function} props.onFetch - 获取数据的函数。
 * @param {React.Ref} ref - 组件的引用。
 *
 * @returns {JSX.Element} 渲染的 OutputPlan 组件。
 */
import React, { useImperativeHandle, forwardRef, useEffect } from 'react';
import { Button, InputNumber, DatePicker, Space, message, Switch, Spin } from 'antd';
import { useTablePipeline } from 'ali-react-table';
import moment from 'moment';
import _ from 'lodash';

import { HttpCode } from '#/utils/contacts.js';
import { useTRState } from '#/utils/trHooks.jsx';
import { MinusCircleOutlined, PlusCircleOutlined } from '#/utils/antdIcons.js';
import { TjSegmented, TjTable, TjChart } from '@/pages/ETrade/components/index.js';
import { TRDefault } from '@/components/index.js';
import OutputPlanReferenceStrategy from '../OutputPlanReferenceStrategy';
import { saveProvincialSpotBiddingPlan } from '../../../service';
import PriceLimitConfigModal from '../PriceLimitConfigModal';
import { columns } from '../../../dictionary';
import styles from './index.less';

const { RangePicker } = DatePicker;
const OutputPlan = forwardRef(
  ({ loading, formValue, outputPlanData, buttonPermissions, power, onFetch }, ref) => {
    const [state, setState] = useTRState({
      tag: 1,
      defaultCapacity: 100,
      upperLimitPrice: 0,
      lowerLimitPrice: 0,
      dataSource: [],
      dateValue: [moment().add(1, 'days'), moment().add(1, 'days')],
      hasPower: buttonPermissions.some(
        (item) => item.menuCode === 'ShorttermForecastingSettingButton',
      ),
      switchState: false,
      disabledSwitch: false,
    });
    const {
      tag,
      dataSource,
      defaultCapacity,
      upperLimitPrice,
      lowerLimitPrice,
      dateValue,
      hasPower,
      switchState,
      disabledSwitch,
    } = state;

    useEffect(() => {
      if (_.isEmpty(outputPlanData)) return;
      const {
        upperLimitPrice,
        lowerLimitPrice,
        stationCapacity,
        planList = [],
        openOrClose,
      } = outputPlanData;
      setState({
        dataSource: planList,
        defaultCapacity: stationCapacity,
        upperLimitPrice,
        lowerLimitPrice,
        switchState: openOrClose,
        tag: 1,
        dateValue: [moment().add(1, 'days'), moment().add(1, 'days')],
      });
    }, [JSON.stringify(outputPlanData)]);

    useImperativeHandle(ref, () => ({
      onSave,
    }));

    const onAdd = (record) => {
      const _dataSource = _.cloneDeep(dataSource);

      const endOutput = record.endOutput + Math.ceil(defaultCapacity / 10); // 每阶段大于装机容量10%

      const mockData = {
        startOutput: record.endOutput,
        endOutput,
        electricityPrice: record.electricityPrice,
        upperLimitPrice: record.upperLimitPrice,
        lowerLimitPrice: record.lowerLimitPrice,
      };

      _dataSource.splice(record.index + 1, 0, mockData);
      sort(_dataSource, record);
    };

    const onDelete = (record) => {
      const _dataSource = _.cloneDeep(dataSource);
      _dataSource.splice(record.index, 1);

      sort(_dataSource, record);
    };

    const sort = (data, record) => {
      const temp = data.reduce((a, b, i) => {
        let temp = {
          ...b,
          index: i,
        };
        // 下一阶段开始出力与上一阶段结束出力保持一致
        if (record.index + 1 === b.index) {
          temp.startOutput = a[a.length - 1].endOutput;
        }
        //最后一段始终为最大装机容量
        if (i === data.length - 1) {
          temp.endOutput = defaultCapacity;
        }

        a.push(temp);
        return a;
      }, []);
      setState({ dataSource: temp });
    };

    const onChange = (e, code, record) => {
      const { index } = record;
      const value = Math.floor(e);
      const data = dataSource.map((t) => {
        const obj = { ...t };
        if (t.index === index) {
          obj[code] = value;
        }
        // 下一阶段开始出力与上一阶段结束出力保持一致
        if (code === 'endOutput' && t.index === index + 1) {
          obj.startOutput = value;
        }
        return obj;
      });

      setState({ dataSource: data });
    };

    const showReferenceStrategy = async () => {
      const { index, data } = await OutputPlanReferenceStrategy.show({ power, formValue });
      if (index === 1) {
        setState({ dataSource: data });
      }
    };

    const showPriceLimitConfig = async () => {
      const { index } = await PriceLimitConfigModal.show({ lowerLimitPrice, upperLimitPrice });
      if (index === 1) {
        onFetch(formValue);
      }
    };

    const getVerifi = () => {
      if (!dataSource.length) {
        message.error('方案不能为空！');
        return;
      }
      if (dataSource.length > 10) {
        message.error('方案段数不可超过十！');
        return;
      }

      let flag = false;
      let priceFlag = false;
      dataSource.reduce((a, b, i) => {
        const { startOutput, endOutput, electricityPrice } = b;
        const space = 1; // 每阶段最小值为上一阶段结束出力加1
        // const space = Math.ceil(defaultCapacity / 10); // 每阶段大于装机容量10%
        if (flag || (i !== 0 && startOutput + space > endOutput)) {
          flag = true;
        }
        if (priceFlag || a.electricityPrice > electricityPrice) {
          priceFlag = true;
        }
        return b;
      }, {});

      if (flag) {
        message.error('每段出力不可小于上一阶段！');
        return;
      }
      if (priceFlag) {
        message.error('电价需大于等于上一阶段！');
        return;
      }
      return true;
    };

    const onSave = async () => {
      const result = getVerifi();
      if (!result) return;
      setState({ disabledSwitch: true });

      const { calendarDate, stationId, marketId } = formValue;
      const planList = dataSource.map(
        ({ electricityPrice, startOutput, endOutput, lowerLimitPrice, upperLimitPrice }) => ({
          electricityPrice,
          startOutput,
          endOutput,
          lowerLimitPrice,
          upperLimitPrice,
        }),
      );

      const reportDate = tag /* && switchState */
        ? [moment(dateValue[0]).format('YYYY-MM-DD'), moment(dateValue[1]).format('YYYY-MM-DD')]
        : [calendarDate, calendarDate];

      const params = {
        planList,
        // type: tag ? (switchState ? '方案' : '手动') : '缺省',
        type: tag ? '方案' : '缺省',
        startDate: reportDate[0],
        endDate: reportDate[1],
        openOrClose: switchState,
        stationId,
        marketId,
      };
      const res = await saveProvincialSpotBiddingPlan(params);
      if (res && res.statusCode === HttpCode.SUCCESS) {
        message.success(res.message || '保存成功');
        setState({
          disabledSwitch: false,
          tag: 1,
          dateValue: [moment().add(1, 'days'), moment().add(1, 'days')],
        });
      } else {
        message.error(res.message || '保存失败');
      }
    };

    const onChangeTag = (tag) => {
      const { planList, defaultPlanList } = outputPlanData;

      setState({ tag, dataSource: tag ? planList : defaultPlanList });
    };

    const _columns = columns.map((t) => {
      switch (t.code) {
        case 'startOutput':
          return {
            ...t,
            render: (v) => (
              <InputNumber
                size="small"
                formatter={(value) => Math.floor(value)}
                parser={(value) => Math.floor(value)}
                value={v}
                disabled={true}
              />
            ),
          };
        case 'endOutput':
          return {
            ...t,
            render: (v, record) => {
              const { index, startOutput } = record;
              const disabled = index !== 0 && index === dataSource.length - 1;
              const min = index === 0 ? 0 : startOutput + 1; // 每阶段最小值为上一阶段结束出力加1
              // const min = index === 0 ? 0 : startOutput + Math.ceil(defaultCapacity / 10); // 每阶段大于装机容量10%
              return (
                <InputNumber
                  size="small"
                  min={min}
                  max={defaultCapacity}
                  step="1"
                  value={v}
                  formatter={(value) => Math.floor(value)}
                  parser={(value) => Math.floor(value)}
                  onChange={(e) => {
                    onChange(e, t.code, record);
                  }}
                  disabled={disabled}
                />
              );
            },
          };
        case 'electricityPrice':
          return {
            ...t,
            render: (v, record) => {
              const { index } = record;
              let min = 0;
              if (index > 0) {
                const { electricityPrice } = dataSource[index - 1];
                min = electricityPrice;
              }
              return (
                <InputNumber
                  min={min}
                  size="small"
                  step="1"
                  value={v}
                  onChange={(e) => {
                    onChange(e, t.code, record);
                  }}
                />
              );
            },
          };
        case 'operation':
          return {
            ...t,
            render(v, record) {
              const isFirst = record.index;
              const max = dataSource.length > 9;
              return (
                <div className={styles.operation}>
                  {!max ? (
                    <PlusCircleOutlined className={styles.addBtn} onClick={() => onAdd(record)} />
                  ) : (
                    ''
                  )}
                  {isFirst ? (
                    <MinusCircleOutlined
                      className={styles.deleteBtn}
                      onClick={() => onDelete(record)}
                    />
                  ) : (
                    ''
                  )}
                </div>
              );
            },
          };
        default:
          return t;
      }
    });

    const pipeline = useTablePipeline({ components: {} })
      .input({
        dataSource,
        columns: _columns,
      })
      .primaryKey('index');

    /**图表配置*/
    const getChartOption = (dataSource) => {
      if (!dataSource?.length) return null;

      const _dataSource = _.cloneDeep(dataSource);
      const lastData = _dataSource[_dataSource.length - 1];
      _dataSource.push({
        startOutput: lastData?.endOutput,
        electricityPrice: lastData?.electricityPrice,
      });
      const CODE1 = 'startOutput';
      const series = [
        {
          name: '电能量报价曲线',
          type: 'line',
          props: {
            step: 'end',
            symbol: 'circle',
          },
          color: '#2174FF',
          dataIndex: 'electricityPrice',
        },
      ];

      return {
        grid: { left: 20, top: 25, right: 20, bottom: 25, containLabel: true },
        series,
        dataset: {
          source: _dataSource,
          dimensions: [CODE1, 'electricityPrice'],
        },
        tooltip: {},
        legend: {},
        xAxis: [{ type: 'category', boundaryGap: false }],
        yAxis: [
          {
            type: 'value',
            name: '单位:元/Mwh',
            nameTextStyle: {
              align: 'left',
            },
          },
        ],
      };
    };

    const disabledDate = (v) => {
      return v <= moment();
    };

    const onStrategyChange = async (checked) => {
      setState({ switchState: checked });
    };

    return (
      <div className={styles.container}>
        <div className={styles.header}>
          <TjSegmented
            value={tag}
            options={[
              { label: '方案', value: 1 },
              { label: '缺省', value: 0 },
            ]}
            onChange={onChangeTag}
          />
          <Space size={16}>
            {tag ? (
              <>
                <RangePicker
                  value={dateValue}
                  onChange={(dateValue) => {
                    setState({ dateValue });
                  }}
                  placeholder={['开始日期', '结束日期']}
                  style={{ width: 240 }}
                  format={'YYYYMMDD'}
                  separator={'-'}
                  disabledDate={disabledDate}
                />
              </>
            ) : (
              ''
            )}

            <Button onClick={showPriceLimitConfig} disabled={!hasPower}>
              配置
            </Button>
            <Button onClick={showReferenceStrategy}>策略引用</Button>
          </Space>
        </div>

        <div className={styles.content}>
          <TjTable
            style={{
              flex: 1,
              overflowY: 'scroll',
              marginTop: 15,
              '--row-height': '28px',
              // '--header-bgcolor': '#383C3E',
              '--header-row-height': '28px',
              '--cell-padding': '6px',
              '--hover-bgcolor': '#222629',
              '--border-color': '#4e5154',
            }}
            useVirtual="auto"
            defaultColumnWidth={90}
            {...pipeline.getProps()}
          />
          <div className={styles.chart}>
            <div className={styles.chartTitle}>价格曲线</div>
            {dataSource.length > 0 ? (
              <TjChart option={getChartOption(dataSource)} />
            ) : (
              <TRDefault type={'emptysm'} message={'暂无数据'} />
            )}
          </div>
        </div>
      </div>
    );
  },
);

export default OutputPlan;
